# -*- encoding: utf-8 -*-

"""
------------------------------------------
@File       : coroutine_by_gather.py
@Author     : maixiaochai
@Email      : maixiaochai@outlook.com
@CreatedOn  : 2021/9/16 16:27
------------------------------------------
    gather 和 wait的区别：
        gather 是需要所有任务都执行结束，如果某一个协程函数崩溃了，则会抛异常，都不会有结果。
            wait 可以定义函数返回的时机，
                可以是 FIRST_COMPLETED(第一个结束的)
                      FIRST_EXCEPTION(第一个出现异常的)
                      ALL_COMPLETED(全部执行完，默认的)
"""
from time import time
from asyncio import sleep, get_event_loop, gather


async def test_a(x):
    print('in test a')
    await sleep(3)
    print('resuming a')
    return x


async def test_b(x):
    print('in test b')
    await sleep(1)
    print('resuming b')
    return x


async def main():
    start = time()
    result_a, result_b = await gather(test_a(1), test_b(3))

    time_cost = round(time() - start, 2)

    print(f"test a's result is {result_a}")
    print(f"test b's result is {result_b}\n")
    print(f"Time cost: {time_cost} s")


if __name__ == '__main__':
    """
    Out:
        in test a
        in test b
        resuming b
        resuming a
        test a's result is 1
        test b's result is 3

        Time cost: 3.0 s

    执行说明：
        可以看到，test_a 和 test_b 是同步在运行。
        由于 test_b 只 sleep 了 1 秒钟，所以 test_b 先输出了 Resuming b,最后将每个协程函数的结果返回。
        注意，这里是 gather()函数里的每一个协程函数都执行完了，它才结束，结果是一个列表，列表里的值顺序和放到 gather函数里的协程的顺序一致
    """
    loop = get_event_loop()
    loop.run_until_complete(main())
